package com.katze.boot.system.controller;

import com.katze.boot.common.exception.BusinessException;
import com.katze.boot.plugins.security.annotations.RestControllerMapping;
import com.katze.boot.plugins.security.annotations.RestRequestMapping;
import com.katze.boot.system.domain.SysLog;
import com.katze.boot.system.service.LogService;
import com.katze.common.DatePattern;
import com.katze.common.Message;
import com.katze.common.Pagination;
import com.katze.common.controller.BaseController;
import com.katze.common.env.AppEnvironment;
import com.katze.common.http.HttpUtils;
import com.katze.common.zip.ScatterSample;
import com.katze.common.zip.ZipArchiveRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMethod;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;


@RestControllerMapping("/log")
public class LogController extends BaseController {
    private static final Logger log = LoggerFactory.getLogger(LogController.class);

    @Autowired
    private LogService logService;

    @RestRequestMapping(permits = "log:view", skip = true)
    public Message logList(Pagination request, SysLog sysLog) {
        return toDataTable(logService.findLogs(request, sysLog));
    }

    @RestRequestMapping(method = RequestMethod.DELETE, permits = "log:delete", description = "删除系统日志")
    public Message deleteLogs(String[] logIds) {
        this.logService.deleteLogs(logIds);
        return Message.ok("删除日志成功");
    }

    @RestRequestMapping(value = "/dir", permits = "log:view", skip = true, description = "查看运行日志")
    public Message dir(String path) throws IOException {
        Path logPath = path == null ? AppEnvironment.LOG_BASE_DIR.getPath() : Paths.get(path);
        List<Map<String, Object>> list = Files.list(logPath)
                .filter(o -> path != null || o.toString().contains(AppEnvironment.APP_NAME.getValue()))
                .map(o -> {
                    File item = o.toFile();
                    Map<String, Object> map = new HashMap<>();
                    map.put("name", item.getName());
                    map.put("path", item.getAbsolutePath());
                    map.put("changeTime", item.lastModified());
                    map.put("type", item.isDirectory() ? "folder" : "file");
                    map.put("size", item.length());
                    map.put("extension", item.isDirectory()? "folder": FilenameUtils.getExtension(item.getName()));
                    map.put("leaf", !item.isDirectory());
                    return map;
                })
                .sorted(Comparator.comparing(x -> (Long) x.get("changeTime"), Comparator.reverseOrder()))
                .collect(Collectors.toList());
        return Message.ok().data(list);
    }

    /**
     * 下载日志文件
     * @param response 响应请求
     * @param paths 文件集
     */
    @RestRequestMapping(value = "/download", method = RequestMethod.POST, description = "下载日志文件")
    public void download(String paths, HttpServletResponse response) {
        try {
            Set<Path> result = Stream.of(paths.split(",")).map(Paths::get).collect(Collectors.toCollection(HashSet::new));
            Path target = AppEnvironment.TEMP_DIR.getPath()
                    .resolve(AppEnvironment.APP_NAME.getValue() + "Log." + DatePattern.YY_DATETIME_NOT_SECOND_FORMAT.format(new Date()) + ".zip");
            if(Files.exists(target)) Files.delete(target);
            ScatterSample.builder(true).foreach(result, file -> new ZipArchiveRequest(file, file.getFileName())).writeTo(target);
            Optional.of(target).filter(Files::exists).ifPresent(file -> HttpUtils.download(response).load(file.toFile()).delete());
        } catch (Exception e) {
            log.error("下载日志失败", e);
            response.setStatus(500);
        }
    }

    @RestRequestMapping(value = "/excel", method = RequestMethod.POST, permits = "log:export")
    public void export(Pagination request, SysLog sysLog, HttpServletResponse response) throws BusinessException {
        try {
            List<SysLog> sysLogs = this.logService.findLogs(request, sysLog).getRecords();
            super.downXlsx("系统日志表", sysLogs, response);
        } catch (Exception e) {
            throw new BusinessException("导出Excel失败", e);
        }
    }
}